package com.cdks.wuxiu.api.service;


import com.cdks.wuxiu.api.component.constant.Constant;
import com.cdks.wuxiu.api.model.dto.UserScoreDTO;
import com.cdks.wuxiu.api.model.dto.WalletInfoDTO;
import com.cdks.wuxiu.api.service.mysql.CallSheetInfoService;
import com.cdks.wuxiu.api.service.mysql.ChatMessageInfoService;
import com.cdks.wuxiu.api.service.mysql.UserBillInfoService;
import com.cdks.wuxiu.api.service.mysql.UserScoreInfoService;
import com.cdks.wuxiu.api.service.mysql.UserWalletInfoService;
import com.cdks.wuxiu.api.service.redis.RedisService;
import com.cdks.wuxiu.api.util.SmsUtils;
import com.cdks.wuxiu.api.util.TimeUtils;
import com.cdks.wuxiu.entity.mysql.CallSheetInfo;

import lombok.extern.slf4j.Slf4j;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;


/**
 * 聊天服务实现类
 */
@Slf4j
@Service
public class ChatServiceImpl implements ChatService {
    @Resource
    private CallSheetInfoService callSheetInfoService;
    @Resource
    private UserScoreInfoService userScoreInfoService;
    @Resource
    private UserWalletInfoService userWalletInfoService;
    @Resource
    private UserBillInfoService userBillInfoService;
    @Resource
    private ChatMessageInfoService chatMessageInfoService;
    @Resource
    private RedisService redisService;    


    @Override
    public int charge(long sender, long recver, long cost) {
        long ret;
        long keepCost;


        //检查是否在通话中，如果在通话中，需要多预留一分钟通话费用
        long nowTime         = TimeUtils.getTimeSecond();
        CallSheetInfo sheet  = callSheetInfoService.getBusyCallByCaller(sender);
        if (sheet != null)
        {
            //计费需要预留的费用（当前用户为通话主叫时，如果异常退出则可能存在应该结算而未结算的费用，所以要根据通话保持时间计算需要预留的费用）
            long callerTime  = redisService.getCallKeepTime(sheet.getCallerId(), sheet.getUcid());
            long answerTime  = redisService.getCallKeepTime(sheet.getAnswerId(), sheet.getUcid());
            long chargeTime  = Math.min(callerTime, answerTime);
            long startTime   = (sheet.getStartTime() > 0) ? sheet.getStartTime() : nowTime;
            long duration    = Math.min(nowTime, chargeTime + 60) - startTime;
            long minutes     = (duration + 59) / 60 + 1;
            
            keepCost  = minutes * sheet.getPayPrice() - sheet.getPayCost();
        }
        else
        {
            keepCost  = 0;
        }

        //获取可用余额。需要保证可用总余额（心豆 + 积分）>= 需要计费的总金额（通话预留+当前消费），否则有可能通话计费时需要抵扣的积分不足
        WalletInfoDTO wallet  = userWalletInfoService.getInfoWithScore(sender, nowTime);
        log.info("chat charge: cost=" + cost + ", keepCost = " + keepCost + ", wallet=" + wallet);
        if ((wallet.getBean() + wallet.getScore()) < (cost + keepCost))
        {
            return -1;
        }

        long costBean;
        long costScore;
        int payType;
        if (wallet.getBean() < cost)
        {
            costBean   = wallet.getBean();
            costScore  = cost - wallet.getBean();
            payType    = Constant.COST_TYPE_SCORE;
        }
        else
        {
            costBean   = cost;
            costScore  = 0;
            payType    = Constant.COST_TYPE_BEAN;
        }

        //查询用户可用积分信息
        UserScoreDTO score  = userScoreInfoService.getBalanceByUser(sender, nowTime);
        log.info("chat charge: score = " + score + ", keepCost = " + keepCost + ", costBean = " + costBean + ", costScore = " + costScore);
        if (score.getScore() < costScore)
        {
            return -2;
        }

        //先扣心豆
        if (costBean > 0)
        {
            //按预付费方式计费
            ret  = userWalletInfoService.decBean(sender, costBean, Constant.STATIS_TYPE_CONSUME, Constant.PAY_MODE_FIRST);
            if (ret < 0)
            {
                SmsUtils.sendManageNotice("聊天计费异常");
                log.error("chat update bean failed: userId = " + sender + ", costBean = " + costBean + ", ret = " + ret);

                return -3;
            }
        }

        //再扣积分
        if (costScore > 0)
        {
            ret  = userScoreInfoService.decByUserId(sender, score.getMinId(), score.getMaxId(), costScore, nowTime);
            if (ret < 0)
            {
                SmsUtils.sendManageNotice("聊天计费异常");
                log.error("chat update score failed: userId = " + sender + ", score = " + score + ", costScore = " + costScore + ", ret = " + ret);

                return -4;
            }
        }

        //保存账单记录
        ret  = userBillInfoService.saveBill(cost, Constant.PRICE_MESSAGE_OTHER, costBean, costScore, Constant.PRICE_MESSAGE_OTHER, sender, recver, payType, Constant.COST_TYPE_COIN, 0, "聊天消息");
        if (ret < 0)
        {
            log.error("chat save bill failed");
        }
        else
        {
            //加收益
            userWalletInfoService.addCoin(recver, Constant.PRICE_MESSAGE_OTHER, Constant.STATIS_TYPE_INWORK);
        }

        return 0;
    }

    @Override
    public int getMessageStatis(Long userId, Long destId) {
        return chatMessageInfoService.getMessageStatis(userId, destId);
    }
}
